package controller;

import java.util.HashMap;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyController implements KeyListener {
    private static HashMap<Integer, Command> keymap = new HashMap<Integer, Command>();
    private static Integer[] keycodes = new Integer[17];

    private static final int MOVE_NORTH = 0;
    private static final int MOVE_NORTHEAST = 1;
    private static final int MOVE_SOUTHEAST = 2;
    private static final int MOVE_SOUTH = 3;
    private static final int MOVE_SOUTHWEST = 4;
    private static final int MOVE_NORTHWEST = 5;
    private static final int USE_DEFAULT_ATTACK = 6;
    private static final int USE_UTILITY_ABILITY = 7;
    private static final int NEXT_UTILITY_ABILITY = 8;
    private static final int PREV_UTILITY_ABILITY = 9;
    private static final int SCROLL_NORTH = 10;
    private static final int SCROLL_NORTHEAST = 11;
    private static final int SCROLL_SOUTHEAST = 12;
    private static final int SCROLL_SOUTH = 13;
    private static final int SCROLL_SOUTHWEST = 14;
    private static final int SCROLL_NORTHWEST = 15;
    private static final int DISMOUNT = 16;

    /**
     * This class contains references to all of the keyboard commands for our
     * character, as well as the KeyListener for the game play window.
     */
    public KeyController() {
        // initialize default keybindings
        keycodes[MOVE_NORTH] = new Integer(KeyEvent.VK_NUMPAD8);
        keycodes[MOVE_NORTHEAST] = new Integer(KeyEvent.VK_NUMPAD9);
        keycodes[MOVE_SOUTHEAST] = new Integer(KeyEvent.VK_NUMPAD3);
        keycodes[MOVE_SOUTH] = new Integer(KeyEvent.VK_NUMPAD2);
        keycodes[MOVE_SOUTHWEST] = new Integer(KeyEvent.VK_NUMPAD1);
        keycodes[MOVE_NORTHWEST] = new Integer(KeyEvent.VK_NUMPAD7);
        keycodes[USE_DEFAULT_ATTACK] = new Integer(KeyEvent.VK_SPACE);
        keycodes[USE_UTILITY_ABILITY] = new Integer(KeyEvent.VK_U);
        keycodes[NEXT_UTILITY_ABILITY] = new Integer(KeyEvent.VK_UP);
        keycodes[PREV_UTILITY_ABILITY] = new Integer(KeyEvent.VK_DOWN);
        keycodes[SCROLL_NORTH] = new Integer(KeyEvent.VK_W);
        keycodes[SCROLL_NORTHEAST] = new Integer(KeyEvent.VK_E);
        keycodes[SCROLL_SOUTHEAST] = new Integer(KeyEvent.VK_C);
        keycodes[SCROLL_SOUTH] = new Integer(KeyEvent.VK_X);
        keycodes[SCROLL_SOUTHWEST] = new Integer(KeyEvent.VK_Z);
        keycodes[SCROLL_NORTHWEST] = new Integer(KeyEvent.VK_Q);
        keycodes[DISMOUNT] = new Integer(KeyEvent.VK_SLASH);

        System.out.println("KeyController constructor called.");
    }

    // methods to add commands to hashmap
    public static void addMoveNorth(Command c) {
        keymap.put(keycodes[MOVE_NORTH], c);
    }
    public static void addMoveNortheast(Command c) {
        keymap.put(keycodes[MOVE_NORTHEAST], c);
    }
    public static void addMoveSoutheast(Command c) {
        keymap.put(keycodes[MOVE_SOUTHEAST], c);
    }
    public static void addMoveSouth(Command c) {
        keymap.put(keycodes[MOVE_SOUTH], c);
    }
    public static void addMoveSouthwest(Command c) {
        keymap.put(keycodes[MOVE_SOUTHWEST], c);
    }
    public static void addMoveNorthwest(Command c) {
        keymap.put(keycodes[MOVE_NORTHWEST], c);
    }
    public static void addUseDefaultAttack(Command c) {
        keymap.put(keycodes[USE_DEFAULT_ATTACK], c);
    }
    public static void addUseUtilityAbility(Command c) {
        keymap.put(keycodes[USE_UTILITY_ABILITY], c);
    }
    public static void addNextUtilityAbility(Command c) {
        keymap.put(keycodes[NEXT_UTILITY_ABILITY], c);
    }
    public static void addPrevUtilityAbility(Command c) {
        keymap.put(keycodes[PREV_UTILITY_ABILITY], c);
    }
    public static void addScrollNorth(Command c) {
        keymap.put(keycodes[SCROLL_NORTH], c);
    }
    public static void addScrollNortheast(Command c) {
        keymap.put(keycodes[SCROLL_NORTHEAST], c);
    }
    public static void addScrollSoutheast(Command c) {
        keymap.put(keycodes[SCROLL_SOUTHEAST], c);
    }
    public static void addScrollSouth(Command c) {
        keymap.put(keycodes[SCROLL_SOUTH], c);
    }
    public static void addScrollSouthwest(Command c) {
        keymap.put(keycodes[SCROLL_SOUTHWEST], c);
    }
    public static void addScrollNorthwest(Command c) {
        keymap.put(keycodes[SCROLL_NORTHWEST], c);
    }
    public static void addDismount(Command c) {
        keymap.put(keycodes[DISMOUNT], c);
    }

    // replace keybinding "oldValue" with keybinding "newValue"
    public static void setKeyBinding(int index, int oldValue, int newValue) {
        keycodes[index] = newValue;
        Command c = keymap.get(oldValue);
        keymap.remove(oldValue);
        keymap.put(newValue, c);
    }

    // load key bindings from an integer array
    public void loadKeyBindings(Integer[] newBindings) {
        for (int i = 0; i < keycodes.length; i++) {
            if (newBindings[i] != null)
                keycodes[i] = newBindings[i];
        }
    }

    // consult keymap for appropriate command, execute if it exists
    public static void executeCommand(Integer keycode) {
        System.out.println("key pressed: "+keycode);
        if (keymap.get(keycode) != null) {
            Command c = keymap.get(keycode);
            c.execute();
        }
    }

    // override key listener methods
    public void keyTyped(KeyEvent e) {

    }
    public void keyPressed(KeyEvent e) {
        System.out.println("Key pressed.");
        Integer keycode = new Integer(e.getKeyCode());
        executeCommand(keycode);
    }
    public void keyReleased(KeyEvent e) {

    }
}